package david.java.tools;


import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.*;

/**
 * @Description: 两表字段对比
 * 表字段对比工具, 支持as别名, 则使用 51行方法 {@link ColumnCompare#getAliasOrCol(String)};
 * 如果直接用ddl对比则使用 {@link ColumnCompare#getColFromDDl(String)}
 * @Author: ZhaoDawei
 * @Date: Create in 2:35 下午 2023/3/31
 */
public class ColumnCompare extends BaseUtil {
    private final static String SOURCE_PATH = "src/tmp/src_col_compare";
    private final static String TARGET_PATH = "target-tmp/col_compare";
    private static Integer MAX_LENGTH = 20;
    private static Set<String> COL_SET = new HashSet<>();

    public static void main(String[] args) throws IOException {
        mkdirIfNotExists(TARGET_PATH);
        List<List<String>> lists = extractCol();
        // System.out.println(lists);
        List<StringBuilder> compare = compare(lists);
        for (StringBuilder sb : compare) {
            System.out.println(sb.toString());

        }

    }

    private static List<List<String>> extractCol() throws IOException {
        List<List<String>> list = new ArrayList<>();    // 0 为第一列, 1 为第二列
        List<String> cols = new ArrayList<>();
        BufferedReader br = new BufferedReader(new FileReader(SOURCE_PATH));
        String line;
        boolean isBlank = false;

        while ((line = br.readLine()) != null) {
            if (StringUtils.isBlank(line)) {   // 遇到了空行
                if (!isBlank) {
                    list.add(cols);
                    cols = new ArrayList<>();
                    isBlank = true;
                }
            } else {
                String lineTrimed = line.trim();
                if (lineTrimed.startsWith("--")) {
                    continue;
                }
                // String  word = getAliasOrCol(lineTrimed);
                String word = getColFromDDl(lineTrimed);

                char[] chars = word.toCharArray();
                StringBuilder sb = new StringBuilder();
                for (char c : chars) {
                    if (c != '`' && c != ',') {
                        sb.append(c);
                    }
                }
                cols.add(sb.toString());
                COL_SET.add(sb.toString());
                MAX_LENGTH = Math.max(MAX_LENGTH, sb.length());
                isBlank = false;
            }
        }
        list.add(cols);
        return list;
    }

    private static String getAliasOrCol(String lineTrimed) {

        //去除掉末尾的注释
        String line = lineTrimed.split("--")[0].trim();

        String[] split = line.split("\\s");

        boolean hasAlias = hasKeyWord(split, "AS");

        String colName = "";
        if (hasAlias) {
            colName = getAlias(split);
        } else {
            colName = getColFromExpr(line);
        }

        return colName;
    }

    private static boolean hasKeyWord(String[] strs, String target) {
        for (int i = 0; i < strs.length; i++) {
            if (strs[i].equalsIgnoreCase(target)) {
                return true;
            }
        }
        return false;
    }

    private static String getAlias(String[] strs) {
        boolean flag = false;
        for (String str : strs) {
            if (str.equalsIgnoreCase("as")) {
                flag = true;
                continue;
            }
            if (StringUtils.isNotBlank(str) && flag) {
                return str;
            }
        }
        return null;
    }


    private static String getColFromExpr(String str) {
        if (str.contains("(")) {
            Stack<Character> stack = new Stack<>();
            StringBuilder sb = new StringBuilder();
            sb.append('`');
            char[] chars = str.toCharArray();
            for (char c : chars) {
                if (c == ')') {
                    break;
                }
                stack.add(c);
            }

            while (!stack.isEmpty()) {
                Character pop = stack.pop();
                if (pop == '.' || pop == '(') {
                    break;
                }
                sb.append(pop);
            }

            return sb.append('`').reverse().toString();
        } else {
            if (str.contains("\\.")) {
                return str.split("\\.")[1];
            } else {
                return str;
            }
        }
    }

    private static List<StringBuilder> compare(List<List<String>> lists) throws IOException {
        List<StringBuilder> result = new ArrayList<>();
        Map<String, Integer> used = new HashMap<>();

        List<String> l1 = lists.get(0);
        List<String> l2 = lists.get(1);


        for (int i = 0; i < l1.size(); i++) {
            result.add(new StringBuilder().append(l1.get(i)));
            used.put(l1.get(i), i);
        }

        for (int i = 0; i < l2.size(); i++) {
            String col = l2.get(i);
            if (used.containsKey(col)) {
                StringBuilder sb = result.get(used.get(col));
                sb.append(blankFilter(col, MAX_LENGTH)).append(col);
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append(blankFilter("", MAX_LENGTH));
                sb.append(col);
                result.add(sb);
            }

        }

        BufferedWriter bw = new BufferedWriter(new FileWriter(TARGET_PATH));

        for (int i = 0; i < result.size(); i++) {
            if (i == 0) {
                bw.write(result.get(i).toString());
            } else {
                bw.newLine();
                bw.write(result.get(i).toString());
            }
        }

        bw.close();


        return result;
    }


}
